using System;
using System.Collections.Generic;
using Game.Core;
using UnityEngine;

namespace Game.Manager
{
	public class AudioManager : Singleton<AudioManager>
	{
		private static readonly object m_Lock;

		private const int SOUNDS_PLAYER_NUM = 14;

		private const int AUDIO_PLAYER_NUM = 15;

		private bool playMusic = true;

		private bool playSound = true;

		private string musicName = string.Empty;

		private string pathName = "Audio/";

		private Dictionary<string, AudioClip> clips = new Dictionary<string, AudioClip>();

		private Dictionary<string, float> playTimes = new Dictionary<string, float>();

		private List<AudioPlayer> audioSources = new List<AudioPlayer>();

		private Camera camera;

		private AudioSource musicPlayer;

		private AudioPlayer[] soundsPlayers;

		private int curSoundsPlayerIndex;

		private AudioSource tempSource;

		private float tempFloat;

		public AudioManager()
		{
			camera = Camera.main;
			if (camera != null)
			{
				musicPlayer = camera.gameObject.AddComponent<AudioSource>();
				musicPlayer.loop = true;
				soundsPlayers = new AudioPlayer[14];
				for (int i = 0; i < 14; i++)
				{
					soundsPlayers[i] = new AudioPlayer();
					soundsPlayers[i].source = camera.gameObject.AddComponent<AudioSource>();
				}
			}
		}

		public void IsMute(bool val)
		{
			musicPlayer.mute = val;
			for (int i = 0; i < soundsPlayers.Length; i++)
			{
				if (soundsPlayers[i] != null && soundsPlayers[i].source != null)
				{
					soundsPlayers[i].source.mute = val;
				}
			}
			for (int j = 0; j < audioSources.Count; j++)
			{
				if (audioSources[j] != null && audioSources[j].source != null)
				{
					audioSources[j].source.mute = val;
				}
			}
		}

		public void UpdateAudioPlayers(float x)
		{
			for (int i = 0; i < audioSources.Count; i++)
			{
				AudioPlayer audioPlayer = audioSources[i];
				if (!audioPlayer.is3DAudio || !audioPlayer.inUse || !audioPlayer.source.isPlaying || !(audioPlayer.owner != null))
				{
					continue;
				}
				if (audioPlayer.owner.gameObject.activeInHierarchy)
				{
					tempFloat = Mathf.Abs(x - audioPlayer.owner.position.x);
					if (tempFloat <= 20f)
					{
						audioPlayer.source.volume = 1f - (float)Math.Pow(tempFloat / 20f, 2.0);
					}
					else
					{
						audioPlayer.source.volume = 0f;
					}
				}
				else
				{
					audioPlayer.source.volume = 0f;
				}
			}
		}

		private void LoadAudioClip(string name)
		{
			if (!clips.ContainsKey(name))
			{
				AudioClip value = Resources.Load(pathName + name) as AudioClip;
				if (!clips.ContainsKey(name))
				{
					clips.Add(name, value);
				}
			}
		}

		public void PlayMusic(string name)
		{
			musicName = name;
			if (!playMusic)
			{
				return;
			}
			if (musicPlayer.clip != null && musicPlayer.clip.name.Equals(musicName))
			{
				if (!musicPlayer.isPlaying)
				{
					musicPlayer.Play();
				}
			}
			else
			{
				LoadAudioClip(name);
				StartPlayMusic(clips[name]);
			}
		}

		private void StartPlayMusic(AudioClip clip)
		{
			if (clip != null)
			{
				if (clip != musicPlayer.clip)
				{
					musicPlayer.clip = clip;
				}
				if (playMusic)
				{
					musicPlayer.Play();
				}
				else
				{
					musicPlayer.Stop();
				}
			}
		}

		public void StopMusic()
		{
			musicPlayer.Stop();
		}

		public void PlaySound(string name, int priority = 0)
		{
			name = name.Trim();
			if (!name.Equals(string.Empty) && playSound && (!playTimes.ContainsKey(name) || !(Time.time - playTimes[name] <= 0.1f)))
			{
				playTimes[name] = Time.time;
				LoadAudioClip(name);
				StartPlaySound(clips[name], priority);
			}
		}

		private void StartPlaySound(AudioClip clip, int priority)
		{
			if (clip == null)
			{
				return;
			}
			bool flag = false;
			int num = curSoundsPlayerIndex;
			for (int i = 0; i < 14; i++)
			{
				num++;
				if (num >= 14)
				{
					num -= 14;
				}
				if (soundsPlayers[num].source.clip == null || !soundsPlayers[num].source.isPlaying || priority >= soundsPlayers[num].priority)
				{
					curSoundsPlayerIndex = num;
					flag = true;
					break;
				}
			}
			if (flag)
			{
				soundsPlayers[curSoundsPlayerIndex].source.clip = clip;
				soundsPlayers[curSoundsPlayerIndex].priority = priority;
				if (playSound)
				{
					soundsPlayers[curSoundsPlayerIndex].source.Play();
				}
				else
				{
					soundsPlayers[curSoundsPlayerIndex].source.Stop();
				}
			}
		}

		public AudioPlayer CreateAudioPlayer(Transform owner, bool is3DAudio = true)
		{
			for (int i = 0; i < audioSources.Count; i++)
			{
				if (!audioSources[i].inUse)
				{
					audioSources[i].inUse = true;
					audioSources[i].owner = owner;
					audioSources[i].is3DAudio = is3DAudio;
					if (is3DAudio)
					{
						audioSources[i].source.volume = 1f;
					}
					return audioSources[i];
				}
			}
			AudioSource source = camera.gameObject.AddComponent<AudioSource>();
			AudioPlayer audioPlayer = new AudioPlayer();
			audioPlayer.source = source;
			if (is3DAudio)
			{
				audioPlayer.source.volume = 0f;
			}
			audioPlayer.inUse = true;
			audioPlayer.owner = owner;
			audioPlayer.is3DAudio = is3DAudio;
			audioSources.Add(audioPlayer);
			return audioPlayer;
		}

		public void PlayAudio(string name, bool isLoop, AudioPlayer player)
		{
			name = name.Trim();
			if (!name.Equals(string.Empty) && playSound)
			{
				LoadAudioClip(name);
				StartPlayAudio(clips[name], isLoop, player);
			}
		}

		private void StartPlayAudio(AudioClip clip, bool isLoop, AudioPlayer player)
		{
			if (!(clip == null) && audioSources.Contains(player) && !(player.source == null) && player.inUse)
			{
				player.source.clip = clip;
				player.source.loop = isLoop;
				if (playSound)
				{
					player.source.Play();
				}
				else
				{
					player.source.Stop();
				}
			}
		}

		public void StopAudio(AudioPlayer player)
		{
			if (player != null && player.source != null)
			{
				player.source.Stop();
			}
		}

		public void RemoveAudio(AudioPlayer player)
		{
			if (player != null && !(player.source == null))
			{
				player.inUse = false;
				player.source.clip = null;
				player.owner = null;
				if (audioSources.Count > 15)
				{
					audioSources.Remove(player);
					UnityEngine.Object.Destroy(player.source);
				}
			}
		}

		public void Clear()
		{
			musicPlayer.clip = null;
			for (int i = 0; i < soundsPlayers.Length; i++)
			{
				soundsPlayers[i].source.clip = null;
			}
			clips.Clear();
			for (int num = audioSources.Count - 1; num >= 0; num--)
			{
				audioSources[num].source.clip = null;
				UnityEngine.Object.Destroy(audioSources[num].source);
				audioSources.RemoveAt(num);
			}
			audioSources.Clear();
		}
	}
}
